package cn.snmp.mutual.org.opennms.protocols.snmp;

import java.util.*;

class SnmpTimer {
    private LinkedList m_list;
    private Thread m_thread;
    private boolean m_exit;
    private Object m_sync;

    SnmpTimer() {
        this.m_exit = false;
        this.m_sync = new Object();
        this.m_list = new LinkedList();
        (this.m_thread = new Thread(new Scheduler())).start();
    }

    void schedule(final Runnable runner, final long milliseconds) {
        if (runner != null) {
            synchronized (this.m_sync) {
                this.m_list.add(new TimeoutElement(milliseconds, runner));
                this.m_sync.notify();
            }
        }
    }

    void cancel() {
        synchronized (this.m_sync) {
            this.m_exit = true;
            this.m_sync.notify();
        }
        try {
            if (!this.m_thread.equals(Thread.currentThread())) {
                this.m_thread.join();
            }
        } catch (InterruptedException ex) {
        }
    }

    private class TimeoutElement {
        public Runnable m_toRun;
        public Date m_when;

        TimeoutElement(final long offset, final Runnable what) {
            (this.m_when = new Date()).setTime(this.m_when.getTime() + offset);
            this.m_toRun = what;
        }
    }

    private class Scheduler implements Runnable {
        public void run() {
            final LinkedList toRun = new LinkedList();
            while (true) {
                synchronized (SnmpTimer.this.m_sync) {
                    if (SnmpTimer.this.m_exit) {
                        return;
                    }
                    if (SnmpTimer.this.m_list.size() == 0) {
                        try {
                            SnmpTimer.this.m_sync.wait();
                        } catch (InterruptedException ex) {
                        }
                        continue;
                    }
                    final Date now = new Date();
                    boolean done = false;
                    long minTime = Long.MAX_VALUE;
                    final ListIterator iter = SnmpTimer.this.m_list.listIterator(0);
                    while (!done && iter.hasNext()) {
                        try {
                            final TimeoutElement elem = (TimeoutElement) iter.next();
                            if (now.after(elem.m_when)) {
                                toRun.add(elem.m_toRun);
                                iter.remove();
                            } else {
                                if (elem.m_when.getTime() >= minTime) {
                                    continue;
                                }
                                minTime = elem.m_when.getTime();
                            }
                        } catch (NoSuchElementException err) {
                            done = true;
                        } catch (ConcurrentModificationException err2) {
                            done = true;
                        }
                    }
                    if (toRun.size() == 0) {
                        minTime -= now.getTime();
                        try {
                            if (minTime > 0L) {
                                SnmpTimer.this.m_sync.wait(minTime);
                            }
                        } catch (InterruptedException ex2) {
                        }
                    }
                }
                if (toRun.size() != 0) {
                    final ListIterator iter2 = toRun.listIterator(0);
                    try {
                        while (true) {
                            final Runnable runner = (Runnable) iter2.next();
                            iter2.remove();
                            runner.run();
                        }
                    } catch (NoSuchElementException err3) {
                    } catch (Throwable t) {
                    }
                }
            }
        }
    }
}
